package org.example.sec09.validator;

import com.seaway.models.sec09.ErrorMessage;
import com.seaway.models.sec09.ValidationCode;
import io.grpc.Metadata;
import io.grpc.Status;
import io.grpc.StatusRuntimeException;
import io.grpc.protobuf.ProtoUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Optional;

/**
 * @author Administrator
 */
public class RequestValidator {
    private static final Metadata.Key<ErrorMessage> ERROR_MESSAGE_KEY = ProtoUtils.keyForProto(ErrorMessage.getDefaultInstance());
    private static final Logger log = LoggerFactory.getLogger(RequestValidator.class);

    public static Optional<StatusRuntimeException> validateAccount(int accountNumber) {
        if (accountNumber > 0 && accountNumber < 11) {
            return Optional.empty();
        }
        var metadata = toMetadata(ValidationCode.INVALID_ACCOUNT);
        return Optional.of(Status.INVALID_ARGUMENT.asRuntimeException(metadata));
    }

    public static Optional<StatusRuntimeException> isAmountDivisibleBy10(int amount) {
        if (amount > 0 && amount % 10 == 0) {
            return Optional.empty();
        }
        var metadata = toMetadata(ValidationCode.INVALID_AMOUNT);
        return Optional.of(Status.INVALID_ARGUMENT.asRuntimeException(metadata));
    }

    public static Optional<StatusRuntimeException> hasSufficientBalance(int amount, int balance) {
        if (amount <= balance) {
            return Optional.empty();
        }
        var metadata = toMetadata(ValidationCode.INVALID_BALANCE);
        return Optional.of(Status.FAILED_PRECONDITION.asRuntimeException(metadata));
    }

    private static Metadata toMetadata(ValidationCode code) {
        var metadata = new Metadata();
        log.info("key.name:{},key.hashCode:{}", ERROR_MESSAGE_KEY.name(), ERROR_MESSAGE_KEY.hashCode());
        var errorMessage = ErrorMessage.newBuilder()
                .setValidationCode(code).build();
        metadata.put(ERROR_MESSAGE_KEY, errorMessage);
        var key = Metadata.Key.of("desc", Metadata.ASCII_STRING_MARSHALLER);
        metadata.put(key, code.toString());
        return metadata;
    }
}
